#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>

// 定义LCD设备结构体
typedef struct {
    char buffer[256];       // 显示缓冲区
    pthread_mutex_t mutex;  // 互斥锁，保护缓冲区访问
    pthread_cond_t cond;    // 条件变量，用于通知显示更新
    int running;            // 运行状态标志
    int width;              // LCD宽度
    int height;             // LCD高度
} LCDDevice;

// 初始化LCD设备
LCDDevice* lcd_init(int width, int height) {
    LCDDevice* lcd = (LCDDevice*)malloc(sizeof(LCDDevice));
    if (!lcd) {
        perror("Failed to allocate memory for LCD");
        return NULL;
    }
    
    lcd->width = width;
    lcd->height = height;
    lcd->running = 1;
    memset(lcd->buffer, 0, sizeof(lcd->buffer));
    
    // 初始化互斥锁和条件变量
    if (pthread_mutex_init(&lcd->mutex, NULL) != 0) {
        perror("Failed to initialize mutex");
        free(lcd);
        return NULL;
    }
    
    if (pthread_cond_init(&lcd->cond, NULL) != 0) {
        perror("Failed to initialize condition variable");
        pthread_mutex_destroy(&lcd->mutex);
        free(lcd);
        return NULL;
    }
    
    printf("LCD device initialized: %dx%d\n", width, height);
    return lcd;
}

// LCD显示线程函数
void* lcd_display_thread(void* arg) {
    LCDDevice* lcd = (LCDDevice*)arg;
    
    while (lcd->running) {
        // 等待显示更新通知
        pthread_mutex_lock(&lcd->mutex);
        pthread_cond_wait(&lcd->cond, &lcd->mutex);
        
        // 模拟LCD显示
        printf("\n[LCD Display %dx%d]\n", lcd->width, lcd->height);
        printf("----------------------------------------\n");
        printf("%s\n", lcd->buffer);
        printf("----------------------------------------\n");
        
        pthread_mutex_unlock(&lcd->mutex);
    }
    
    printf("LCD display thread exiting\n");
    return NULL;
}

// 更新LCD显示内容
void lcd_update(LCDDevice* lcd, const char* text) {
    if (!lcd || !text) return;
    
    pthread_mutex_lock(&lcd->mutex);
    // 复制文本到缓冲区，确保不超过缓冲区大小
    strncpy(lcd->buffer, text, sizeof(lcd->buffer) - 1);
    lcd->buffer[sizeof(lcd->buffer) - 1] = '\0';
    
    // 通知显示线程有新内容
    pthread_cond_signal(&lcd->cond);
    pthread_mutex_unlock(&lcd->mutex);
}

// 关闭LCD设备
void lcd_close(LCDDevice* lcd) {
    if (!lcd) return;
    
    lcd->running = 0;
    // 唤醒可能在等待的显示线程
    pthread_cond_signal(&lcd->cond);
    
    // 销毁互斥锁和条件变量
    pthread_mutex_destroy(&lcd->mutex);
    pthread_cond_destroy(&lcd->cond);
    
    free(lcd);
    printf("LCD device closed\n");
}

// 模拟用户输入线程
void* user_input_thread(void* arg) {
    LCDDevice* lcd = (LCDDevice*)arg;
    char input[256];
    
    while (lcd->running) {
        printf("\nEnter text to display on LCD (or 'exit' to quit): ");
        fflush(stdout);
        
        if (fgets(input, sizeof(input), stdin) == NULL) {
            break;
        }
        
        // 移除换行符
        input[strcspn(input, "\n")] = '\0';
        
        // 检查是否退出
        if (strcmp(input, "exit") == 0) {
            lcd->running = 0;
            pthread_cond_signal(&lcd->cond); // 唤醒显示线程
            break;
        }
        
        // 更新LCD显示
        lcd_update(lcd, input);
        sleep(1); // 简单延迟，模拟操作间隔
    }
    
    printf("User input thread exiting\n");
    return NULL;
}

int main() {
    // 初始化LCD设备，分辨率为80x24
    LCDDevice* lcd = lcd_init(80, 24);
    if (!lcd) {
        return 1;
    }
    
    pthread_t display_thread, input_thread;
    
    // 创建LCD显示线程
    if (pthread_create(&display_thread, NULL, lcd_display_thread, lcd) != 0) {
        perror("Failed to create display thread");
        lcd_close(lcd);
        return 1;
    }
    
    // 创建用户输入线程
    if (pthread_create(&input_thread, NULL, user_input_thread, lcd) != 0) {
        perror("Failed to create input thread");
        pthread_cancel(display_thread);
        lcd_close(lcd);
        return 1;
    }
    
    // 等待线程结束
    pthread_join(input_thread, NULL);
    pthread_join(display_thread, NULL);
    
    // 清理资源
    lcd_close(lcd);
    
    return 0;
}
